from typing import Union, Type

Numeric = Union[float, int]


class NumberUtils(object):

    @classmethod
    def safe_divide(cls, n1: Numeric, n2: Numeric, r=1, lower_limit: Numeric = None, upper_limit: Numeric = None) -> Numeric:
        """如果除数为0或者为空, 那么返回0, 否则正常除法保留r位小数"""
        if n1 is None or not n2:
            return 0
        return cls.limit_number(round(n1 / n2, r), lower_limit, upper_limit)

    @classmethod
    def safe_percent(cls, n1, n2, r=1, lower_limit: Numeric = None, upper_limit: Numeric = None) -> str:
        """百分比计算, 自动在末尾添加%
        >>> NumberUtils.safe_percent(100, 50, r=2, lower_limit=1, upper_limit=1.5)
        '150.0%'  # 保留2位小数, 限制在指定的上下限中
        """
        x = cls.safe_divide(n1, n2, r=r+2, lower_limit=lower_limit, upper_limit=upper_limit)
        return str(cls.limit_number(round(x * 100, r))) + '%'

    @classmethod
    def ensure_non_negative(cls, n1: Numeric):
        """返回一个数, 如果小于0, 则返回0"""
        return 0 if n1 < 0 else n1

    @classmethod
    def limit_number(cls, number: Numeric, lower_limit: Numeric = None, upper_limit: Numeric = None) -> Numeric:
        """限制数字的上下限, 如果大于上限或者小于下限, 那么返回对应的上限或者下限"""
        if lower_limit and number < lower_limit:
            return lower_limit
        if upper_limit and number > upper_limit:
            return upper_limit
        return number


